package org.njo.webapp.root.model.activity;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.ho.yaml.Yaml;
import org.njo.webapp.root.model.dao.DTSFieldDAO;
import org.njo.webapp.root.utility.ObjectExistsException;
import org.njo.webapp.root.utility.ObjectNotExistsException;
import org.njo.webapp.root.utility.SystemContext;

public class DTSActivity {

    /**
     * Log Object.
     */
    private static Log logger = LogFactory.getLog(DTSActivity.class);

    public List getFieldList() {
        Connection connection = null;
        DTSFieldDAO fieldDAO = null;
        List result = new ArrayList();
        
        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);
            
            List dataList = fieldDAO.selectAllFields(1, Integer.MAX_VALUE);
            
            for (int i=0;i<dataList.size();i++) {
                String[] data = (String[])dataList.get(i);
                String yamlString = data[1];
                Object yamlObject = Yaml.load(yamlString);
                result.add(yamlObject);
            }

            return result;
        } catch (SQLException ex) {
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    public void addField(String argFieldName, Object argYAMLObject,
            String argFieldDescription) throws ObjectExistsException {

        Connection connection = null;
        DTSFieldDAO fieldDAO = null;

        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);
            String yamlString = Yaml.dump(argYAMLObject);
            fieldDAO.insertField(argFieldName, yamlString, argFieldDescription);

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                if (logger.isErrorEnabled()) {
                    logger.error(tw);
                }
            }
            if (ex.getErrorCode() == 1) { // ORACLE 主键重复
                throw new ObjectExistsException("aready inserted.");
            }
            if (ex.getErrorCode() == 1062) { // MySQL 主键重复
                throw new ObjectExistsException("aready inserted.");
            }
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }
    
    /**
     * 
     * 
     * @param argMessageKey
     * @return
     * @throws ObjectNotExistsException
     */
    public Object getFiled(String argFieldName)
            throws ObjectNotExistsException {
        // selectByMessageKey
        Connection connection = null;
        DTSFieldDAO fieldDAO = null;
        Object fieldObject = null;

        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);
            String[] fieldData = fieldDAO.selectFieldByName(argFieldName);

            fieldObject = Yaml.load(fieldData[1]);

            return fieldObject;
        } catch (SQLException ex) {
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    public void saveField(String argFieldName, Object argYAMLObject,
            String argFieldDescription) {

        Connection connection = null;
        DTSFieldDAO fieldDAO = null;

        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);
            String yamlString = Yaml.dump(argYAMLObject);
            fieldDAO.updateField(argFieldName, yamlString, argFieldDescription);

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                if (logger.isErrorEnabled()) {
                    logger.error(tw);
                }
            }
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }

    }

    public void removeField(String[] argFieldNames) {
        Connection connection = null;
        DTSFieldDAO fieldDAO = null;

        try {
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);

            for (int i = 0; argFieldNames != null
                    && i < argFieldNames.length; i++) {
                String argFieldName = argFieldNames[i];
                fieldDAO.deleteFieldByName(argFieldName);
            }

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                if (logger.isErrorEnabled()) {
                    logger.error(tw);
                }
            }
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    public List exportFiled(String[] argFieldNames) {
        Connection connection = null;
        DTSFieldDAO fieldDAO = null;
        List result = new ArrayList();
        
        try {
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);

            for (int i = 0; argFieldNames != null
                    && i < argFieldNames.length; i++) {
                String argFieldName = argFieldNames[i];
                String[] data = fieldDAO.selectFieldByName(argFieldName);
                String yamlString = data[1];
                Object yamlObject = Yaml.load(yamlString);
                result.add(yamlObject);
            }
            return result;
        } catch (SQLException ex) {
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }
    
    public void importField(List importList) {
        Connection connection = null;
        DTSFieldDAO fieldDAO = null;

        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);
            for (int i=0;i<importList.size();i++) {
                Map fieldMap = (Map)importList.get(i);
                String name = (String)fieldMap.get("field_physical_name");
                String yamlString = Yaml.dump(fieldMap);
                String description = (String)fieldMap.get("field_description");
                int cnt = fieldDAO.updateField(name, yamlString, description);
                if (cnt!=1) {
                    fieldDAO.insertField(name, yamlString, description);
                }
            }
            

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                if (logger.isErrorEnabled()) {
                    logger.error(tw);
                }
            }
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }
    

    public List getFieldSetList() {
        Connection connection = null;
        DTSFieldDAO fieldDAO = null;
        List result = new ArrayList();
        
        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);
            
            List dataList = fieldDAO.selectAllFieldSets(1, Integer.MAX_VALUE);
            
            for (int i=0;i<dataList.size();i++) {
                String[] data = (String[])dataList.get(i);
                String yamlString = data[1];
                Object yamlObject = Yaml.load(yamlString);
                result.add(yamlObject);
            }

            return result;
        } catch (SQLException ex) {
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    public void addFieldSet(String argFieldSetName, Object argYAMLObject,
            String argFieldSetDescription) throws ObjectExistsException {

        Connection connection = null;
        DTSFieldDAO fieldDAO = null;

        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);
            String yamlString = Yaml.dump(argYAMLObject);
            fieldDAO.insertFieldSet(argFieldSetName, yamlString, argFieldSetDescription);

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                if (logger.isErrorEnabled()) {
                    logger.error(tw);
                }
            }
            if (ex.getErrorCode() == 1) { // ORACLE 主键重复
                throw new ObjectExistsException("aready inserted.");
            }
            if (ex.getErrorCode() == 1062) { // MySQL 主键重复
                throw new ObjectExistsException("aready inserted.");
            }
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }

    }
    
    /**
     * 
     * 
     * @param argMessageKey
     * @return
     * @throws ObjectNotExistsException
     */
    public Object getFiledSet(String argFieldSetName)
            throws ObjectNotExistsException {
        // selectByMessageKey
        Connection connection = null;
        DTSFieldDAO fieldDAO = null;
        Object fieldObject = null;

        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);
            String[] fieldData = fieldDAO.selectFieldSetByName(argFieldSetName);

            fieldObject = Yaml.load(fieldData[1]);

            return fieldObject;
        } catch (SQLException ex) {
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    public void saveFieldSet(String argFieldSetName, Object argYAMLObject,
            String argFieldSetDescription) {

        Connection connection = null;
        DTSFieldDAO fieldDAO = null;

        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);
            String yamlString = Yaml.dump(argYAMLObject);
            fieldDAO.updateFieldSet(argFieldSetName, yamlString, argFieldSetDescription);

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                if (logger.isErrorEnabled()) {
                    logger.error(tw);
                }
            }
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }

    }

    public void removeFieldSet(String[] argFieldSetNames) {
        Connection connection = null;
        DTSFieldDAO fieldDAO = null;

        try {
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);

            for (int i = 0; argFieldSetNames != null
                    && i < argFieldSetNames.length; i++) {
                String argFieldSetName = argFieldSetNames[i];
                fieldDAO.deleteFieldSetByName(argFieldSetName);
            }

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                if (logger.isErrorEnabled()) {
                    logger.error(tw);
                }
            }
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    public List exportFiledSet(String[] argFieldSetNames) {
        Connection connection = null;
        DTSFieldDAO fieldDAO = null;
        List result = new ArrayList();
        
        try {
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);

            for (int i = 0; argFieldSetNames != null
                    && i < argFieldSetNames.length; i++) {
                String argFieldSetName = argFieldSetNames[i];
                String[] data = fieldDAO.selectFieldSetByName(argFieldSetName);
                String yamlString = data[1];
                Object yamlObject = Yaml.load(yamlString);
                result.add(yamlObject);
            }
            return result;
        } catch (SQLException ex) {
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }
    
    public void importFieldSet(List importList) {
        Connection connection = null;
        DTSFieldDAO fieldDAO = null;

        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);
            for (int i=0;i<importList.size();i++) {
                Map fieldMap = (Map)importList.get(i);
                String name = (String)fieldMap.get("field_set_physical_name");
                String yamlString = Yaml.dump(fieldMap);
                String description = (String)fieldMap.get("field_set_description");
                int cnt = fieldDAO.updateFieldSet(name, yamlString, description);
                if (cnt!=1) {
                    fieldDAO.insertFieldSet(name, yamlString, description);
                }
            }
            

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                if (logger.isErrorEnabled()) {
                    logger.error(tw);
                }
            }
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    public List getFieldTypeList() {
        Connection connection = null;
        DTSFieldDAO fieldDAO = null;
        List result = null;
        
        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);
            result = fieldDAO.selectFieldType();
            return result;
        } catch (SQLException ex) {
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }
    
    public List getDBKindList() {
        Connection connection = null;
        DTSFieldDAO fieldDAO = null;
        List result = null;
        
        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);
            result = fieldDAO.selectDBKind();
            return result;
        } catch (SQLException ex) {
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }
    
    public void addSQLDDL(String argGenName, Object argYAMLObject) throws ObjectExistsException {

        Connection connection = null;
        DTSFieldDAO fieldDAO = null;

        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);
            String yamlString = Yaml.dump(argYAMLObject);
            fieldDAO.insertGenSQLDDL(argGenName, yamlString);

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                if (logger.isErrorEnabled()) {
                    logger.error(tw);
                }
            }
            if (ex.getErrorCode() == 1) { // ORACLE 主键重复
                throw new ObjectExistsException("aready inserted.");
            }
            if (ex.getErrorCode() == 1062) { // MySQL 主键重复
                throw new ObjectExistsException("aready inserted.");
            }
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }
    
    public void saveSQLDDL(String argGenName, Object argYAMLObject) throws ObjectExistsException {

        Connection connection = null;
        DTSFieldDAO fieldDAO = null;

        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);
            String yamlString = Yaml.dump(argYAMLObject);
            fieldDAO.updateGenSQLDDL(argGenName, yamlString);

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                if (logger.isErrorEnabled()) {
                    logger.error(tw);
                }
            }
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    public void removeSQLDDL(String[] argGenNames) {
        Connection connection = null;
        DTSFieldDAO fieldDAO = null;

        try {
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);

            for (int i = 0; argGenNames != null
                    && i < argGenNames.length; i++) {
                String argGenName = argGenNames[i];
                fieldDAO.deleteGenSQLDDLByName(argGenName);
            }

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                if (logger.isErrorEnabled()) {
                    logger.error(tw);
                }
            }
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    
    public List getDDLGENList() {
        Connection connection = null;
        DTSFieldDAO fieldDAO = null;
        List result = null;
        
        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);
            
            result = fieldDAO.selectDDLGENList();

            return result;
        } catch (SQLException ex) {
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    /**
     * 
     * 
     * @param argMessageKey
     * @return
     * @throws ObjectNotExistsException
     */
    public Map getDDLGEN(String argGenName)
            throws ObjectNotExistsException {
        // selectByMessageKey
        Connection connection = null;
        DTSFieldDAO fieldDAO = null;
        Map fieldObject = null;

        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);
            fieldObject = fieldDAO.selectDDLGENByName(argGenName);

            return fieldObject;
        } catch (SQLException ex) {
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }
    
    public Map getDDLGENData(String argGenName) throws ObjectNotExistsException {
        // selectByMessageKey
        Connection connection = null;
        DTSFieldDAO fieldDAO = null;
        Map fieldObject = null;

        // access the database.
        try {
            // open the database connection.
            connection = SystemContext.openConnection();
            fieldDAO = new DTSFieldDAO(connection);
            fieldObject = fieldDAO.selectDDLGENByName(argGenName);

            String[] field_set_physical_names = (String[])fieldObject.get("field_set_physical_names");
            String to_kind = (String)fieldObject.get("gen_to_kind");
            List fieldSetList = new ArrayList();
            for (int i=0;i<field_set_physical_names.length;i++) {
                String[] fieldSetData = (String[])fieldDAO.selectFieldSetByName(field_set_physical_names[i]);
                Map fieldset = (Map)Yaml.load(fieldSetData[1]);
                List fieldList = (List)fieldset.get("fields");
                for (int j=0;j<fieldList.size();j++) {
                    Map field = (Map)fieldList.get(j);
                    String field_physical_name = (String)field.get("field_physical_name");
                    String[] fieldData = fieldDAO.selectFieldByName(field_physical_name);
                    Map field_d = (Map)Yaml.load(fieldData[1]);
                    String field_type = (String)field_d.get("field_type");
                    Map field_type_mapping = fieldDAO.selectFTMByName(field_type, to_kind);
                    String d_type = (String)field_type_mapping.get("to_kind_field_type");
                    field_d.put("field_type", d_type);
                    
                    field.putAll(field_d);
                }
                fieldSetList.add(fieldset);
            }
            fieldObject.put("fieldSetList", fieldSetList);
            
            return fieldObject;
        } catch (SQLException ex) {
            if (logger.isErrorEnabled()) {
                logger.error(ex);
            }
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }
    
    
}
